package com.appspot.moviesessions.infrastructure.persistence;

import java.beans.PropertyDescriptor;
import java.util.Map;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Unique;

import com.appspot.moviesessions.model.Movie;
import com.appspot.moviesessions.model.Movie.Fields;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.Key;

import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public final class MovieRecord implements Movie {
	@Persistent
	private String actors;

	@Persistent
	private String director;

	@Persistent
	private String genre;

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;

	@Persistent
	@Unique
	private String name;

	@Persistent
	private String plot;

	@Persistent
	private String poster;

	@Persistent
	private String posterKey;

	@Persistent
	private String rated;

	@Persistent
	private String rating;

	@Persistent
	private String runtime;

	@Persistent
	private String votes;

	@Persistent
	private String writer;

	public MovieRecord() {
	}

	public MovieRecord(Key key, String name) {
		this.key = key;
		this.name = name;
	}

	public MovieRecord(String name) {
		super();
		this.name = name;
	}

	public String getActors() {
		return actors;
	}

	public String getDirector() {
		return director;
	}

	public String getGenre() {
		return genre;
	}

	@Override
	public Long getId() {
		return (key == null) ? null : key.getId();
	}

	public Key getKey() {
		return key;
	}

	public String getName() {
		return name;
	}

	public String getPlot() {
		return plot;
	}

	public String getPoster() {
		return poster;
	}

	public String getRated() {
		return rated;
	}

	public String getRating() {
		return rating;
	}

	public String getRuntime() {
		return runtime;
	}

	public String getVotes() {
		return votes;
	}

	public String getWriter() {
		return writer;
	}

	public void setActors(String actors) {
		this.actors = actors;
	}

	public void setDirector(String director) {
		this.director = director;
	}

	public void setGenre(String genre) {
		this.genre = genre;
	}

	public void setPlot(String plot) {
		this.plot = plot;
	}

	public void setPoster(String poster) {
		this.poster = poster;
	}

	public void setRated(String rated) {
		this.rated = rated;
	}

	public void setRating(String rating) {
		this.rating = rating;
	}

	public void setRuntime(String runtime) {
		this.runtime = runtime;
	}

	public void setVotes(String votes) {
		this.votes = votes;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getPosterKey() {
		return posterKey;
	}

	public void setPosterKey(String posterKey) {
		this.posterKey = posterKey;
	}

	public void update(Map<Fields, Object> fields) {
		BeanWrapper wrapper = new BeanWrapperImpl(this);
		PropertyDescriptor[] descriptors = wrapper.getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : descriptors) {
			String property = propertyDescriptor.getName();
			Fields field = null;
			if ((field = Fields.match(property.toUpperCase())) != null) {
				if (fields.containsKey(field)) {
					wrapper.setPropertyValue(property, fields.get(field));
				}

			}

		}
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof MovieRecord))
			return false;
		MovieRecord castOther = (MovieRecord) other;
		return new EqualsBuilder().append(name, castOther.name).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(name).toHashCode();
	}

}